www.gusucode.com > php框架系统:MDPHP麦迪源码 v1.xPHP源码程序 > php框架系统:MDPHP麦迪源码 v1.x/mdphp_v1.0.beta/mdphp_v1.0.beta/Library/Custom.php
<?php /** * 麦迪核心功能集 * @author: 麦迪科技 <i@md8.cc> * @link: http://soft.md8.cc * @version: 1.1 */ namespace MDPHP; final class Custom{ //执行时间记录变量 static $workTime=array(); /** * 单入口初始化 */ static public function start(){ self::init(); self::route(); self::run(); } static public function init(){ //根目录 if(!file_exists(MD_PATH)){ mkdir(MD_PATH); file_put_contents(MD_PATH . 'index.html', ''); } //公用文件 if(!file_exists(MD_PATH . 'config.php')) copy(MD_ROOT.'Library/Default/config', MD_PATH.'config.php'); if(!file_exists(MD_PATH . 'function.php')) file_put_contents(MD_PATH . 'function.php', ''); //引入配置 C(include MD_PATH.'config.php'); $path = array( C('LAYER_V'), C('LAYER_A'), C('LAYER_C'), C('LAYER_R'), C('LAYER_P'), C('LAYER_A').'/'.ucwords(C('DEFAULT.CONTROLLER')), C('LAYER_V').'/'.ucwords(C('DEFAULT.CONTROLLER')) ); foreach($path as $value){ if(!file_exists(MD_PATH.$value.'/')){ mkdir(MD_PATH.$value.'/') or error('无法初始化项目,请检查文件权限。'); file_put_contents(MD_PATH.$value.'/index.html', ''); } } //默认视图 if(!file_get_contents($file=MD_PATH.end($path).'/'.C('DEFAULT.ACTION').C('TMPL_SUFFIX'))) copy(MD_ROOT.'Library/Default/view', MD_PATH.C('LAYER_V').'/Index/index.html'); //默认控制器 if(!file_exists($file=MD_PATH.C('LAYER_C').'/'.C('DEFAULT.CONTROLLER').'.php')) copy(MD_ROOT.'Library/Default/controller', $file); } /** * 路由 */ static public function route(){ //获取地址 if(substr($_SERVER['REQUEST_URI'], 0, $n=strlen($_SERVER['SCRIPT_NAME'])) == $_SERVER['SCRIPT_NAME']){ define('MD_BOOT_FILE', getFileName($_SERVER['SCRIPT_NAME'])); $url = substr($_SERVER['REQUEST_URI'], $n); }elseif(substr($_SERVER['REQUEST_URI'], 0, $n=strlen(dirname($_SERVER['SCRIPT_NAME']))) == dirname($_SERVER['SCRIPT_NAME'])){ $url = ltrim(substr($_SERVER['REQUEST_URI'], $n), '/'); }else{ $url = $_SERVER['PATH_INFO']; } define('MD_PATH_INFO', $url); $url=trim_left($url, '/'); parse:{ //获取模块、控制器、动作 $url=parse_url($url); $array=(empty($url['path']) ? array() : explode('/', $url['path'])); $count=count($array); $default=C('DEFAULT'); $defval=array($default['MODULE'], $default['CONTROLLER'], $default['ACTION']); for($i=0; $i<($count>3 ? 3 : $count); $i++){ $array[$i] = (empty($array[$i]) ? $defval[$i] : $array[$i]); } switch($count){ case 0: #默认 $m=$default['MODULE']; $c=$default['CONTROLLER']; $a=$default['ACTION']; break; case 1: #方法 $m=$default['MODULE']; $c=$default['CONTROLLER']; $a=$array[0]; array_shift($array); break; case 2: #控制器/方法 $m=$default['MODULE']; $c=$array[0]; $a=$array[1]; $array = array_splice($array, 2); break; default: #模块/控制器/方法 $m=$array[0]; $c=$array[1]; $a=$array[2]; $array = array_splice($array, 3); break; } //智能模块检测 if(in_array_case($c, array('_mdphp'))){ #系统 $path=$c; $m=I('g.m', $default['MODULE'], 'ucwords'); }else{ if(file_exists(MD_PATH. (in_array_case($m, $default['MODULE']) && !file_exists(MD_PATH.ucwords($m).'/') ? '' : (ucwords($m).'/')) .C('LAYER_C').'/'.$c.'.php')){ #绝对 }elseif(file_exists(MD_PATH.$c.'/')){ #简写 $m=$c; $c=$default['CONTROLLER']; } } $modulePath = (in_array_case($m, $default['MODULE']) && !file_exists(MD_PATH.ucwords($m).'/') ? '' : (ucwords($m).'/')); } //检测路由规则 if(!isset($config)){ $config = array(); $code = ($modulePath ? file_get_contents(MD_PATH.$modulePath.'config.php') : '') . file_get_contents(MD_PATH.'config.php'); //路由规则状态 preg_match('/[\'"]URL_ROUTER[\'"]\s*=>\s*(\S+)\s*(?:,|$)/', $code, $config[0]); $config[0] = str_replace('true', 1, strtolower(isset($config[0][1]) ? $config[0][1] : 0)) > 0; //路由规则开启 if($config[0]){ $url = MD_PATH_INFO; //路由规则列表 preg_match('/[\'"]URL_ROUTE_RULES[\'"]\s*=>\s*array\s*\(([\s\S]+)\)\s*(?:,|$)/', $code, $config[1]); if(isset($config[1][1])) preg_match_all('/[\'"](.*?)[\'"]\s*=>\s*[\'"](.*?)[\'"]\s*(?:,|$)/', $config[1][1], $config[1]); else $config[1][1] = array(); } } if(isset($config[0]) && $config[0]){ for($i=0; $i<count($config[1][1]); $i++){ if(($match=preg_replace($config[1][1][$i], $config[1][2][$i], $url)) != $url){ if(($n=strpos($match, '?')) !== false){ parse_str(substr($match, $n+1), $_GET); $url = substr($match, 0, $n); $config = true; } } } if($config===true) goto parse; } //检测模块是否存在 if($modulePath && !file_exists(MD_PATH.$modulePath)) error('Module_Not_Exist', MD_PATH.$modulePath); //更新模块信息 if($modulePath){ C(include MD_PATH . $modulePath . 'config.php'); if(file_exists(MD_PATH.$modulePath.'function.php')) require MD_PATH.$modulePath.'function.php'; } //设置常量 define('MD_PATH_MODULE', $modulePath); #模块目录 ############################### APP ############################### define('APP_PATH_COMPLETE', APP_PATH . MD_PATH_MODULE); #完整目录 define('APP_PATH_VIEW', APP_PATH_COMPLETE . C('LAYER_V') . '/'); #视图目录 define('APP_PATH_CACHE', APP_PATH_COMPLETE . C('LAYER_R') . '/'); #缓存目录 define('APP_PATH_COMMON', APP_PATH_COMPLETE . C('LAYER_A') . '/'); #公共目录 define('APP_PATH_PLUGIN', APP_PATH_COMPLETE . C('LAYER_P') . '/'); #插件目录 define('APP_PATH_CONTROLLER', APP_PATH_COMPLETE . C('LAYER_C') . '/'); #控制器目录 ############################## MDPHP ############################## define('MD_PATH_COMPLETE', MD_PATH . MD_PATH_MODULE); #完整目录 define('MD_PATH_VIEW', MD_ROOT . APP_PATH_VIEW); #视图目录 define('MD_PATH_CACHE', MD_ROOT . APP_PATH_CACHE); #缓存目录 define('MD_PATH_COMMON', MD_ROOT . APP_PATH_COMMON); #公共目录 define('MD_PATH_PLUGIN', MD_ROOT . APP_PATH_PLUGIN); #插件目录 define('MD_PATH_CONTROLLER', MD_ROOT . APP_PATH_CONTROLLER); #控制器目录 ############################## SYSTEM ############################## self::$workTime['stop'] = microtime(true); define('EXECUTE_TIME', round(self::$workTime['stop']-self::$workTime['start'], 4)); #处理时间 define('IS_GET', $_SERVER['REQUEST_METHOD'] == 'GET'); #GET请求 define('IS_POST', $_SERVER['REQUEST_METHOD'] == 'POST'); #POST请求 define('IS_PUT', $_SERVER['REQUEST_METHOD'] == 'PUT'); #PUT请求 define('IS_DELETE', $_SERVER['REQUEST_METHOD'] == 'DELETE'); #DELETE请求 define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); #AJAX请求 define('MDPHP_CACHE', true); #安全标志 //后缀处理 if(!defined('MD_SUFFIX') && ($ext=getFileExt($a))){ define('MD_SUFFIX', $ext); #伪静态后缀 $a = substr($a, 0, -strlen(MD_SUFFIX)-1); } //参数处理 for($i=0; $i<(count($array)/2); $i++){ $_GET[@$array[$i*2]] = @$array[($i*2)+1]; } //定义操作 define('MD_MOD', ucwords($m)); #模块 define('MD_CTR', $c); #控制器 define('MD_ACT', $a); #动作 //检测Action if(file_exists($actionPath=MD_PATH_CONTROLLER.MD_CTR.'Action.php')) require $actionPath; //引入代码 if(isset($path)){ define('MD_PREFIX_CTR', ''); import('$->Library->Special->' . MD_CTR); }else{ $path = MD_PATH_CONTROLLER . MD_CTR . '.php'; if(file_exists($path)) require $path; else error('Controller_Not_Exist', $path); define('MD_PREFIX_CTR', '_'); } } /** * 跑方法 */ static public function run(){ //实例化控制器 $MDPHP = self::call(MD_PREFIX_CTR . MD_CTR); //检测伪静态后缀 /*if(defined('MD_SUFFIX') && MD_SUFFIX != C('TMPL_SUFFIX')){ $MDPHP -> jump(U(MD_CTR . '/' . MD_ACT)); }*/ //更新公共信息 require MD_PATH . 'function.php'; //设置全局领域 $GLOBALS['MDPHP'] =& $MDPHP; //设置协议头 //header('Cache-control: ' . C('HTTP_CACHE_CONTROL')); #页面缓存控制 header('X-Powered-By:MDPHP'); if(strtolower($charset=C('DOC_CHARSET')) != 'utf-8') header('Content-Type:text/html; charset=' . $charset); //开启SESSION C('SESSION.START') && session_start(); //设置时区 date_default_timezone_set(C('DEFAULT.TIMEZONE')); //方法检测 if(!method_exists($MDPHP, MD_ACT)){ if(method_exists($MDPHP, '__empty')) $MDPHP->__empty(); else error('Action_Not_Exist', MD_ACT); } //非调试模式 if(!constant('APP_DEBUG')){ //获取缓存 $Cache = new Cache; $data = $Cache->get(MD_CTR.MD_ACT); if(is_null($data)){ //GZIP压缩 $GZIP = C('COMPRESS.GZIP'); //缓冲开始 ob_start(); //开始运行 method_exists($MDPHP, '__init') && $MDPHP->__init(); $MDPHP->{MD_ACT}(); //缓冲结束 $data = ob_get_clean(); //GZIP处理 $data = $GZIP ? ob_gzip($data) : $data; //添加缓存 $Cache->add(MD_CTR.MD_ACT, $data); } echo $data; return; } //正常运行 method_exists($MDPHP, '__init') && $MDPHP->__init(); $MDPHP->{MD_ACT}(); //DEBUG处理 if(MD_PREFIX_CTR && constant('APP_DEBUG_TOOL')){ $const = get_defined_constants(true); self::log(array( 'CONST' => array_map(function($v){ return htmlspecialchars($v); }, $const['user']), 'REQUEST' => array('GET'=>I('G'), 'POST'=>I('P'), 'COOKIE'=>cookie()), ), 'S'); $debug = self::log(); include MD_ROOT.'Library/Default/debug'; } } /** * 致命错误处理函数 */ static public function fatalError(){ if($info = error_get_last()){ switch($info['type']){ case E_ERROR: case E_PARSE: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_USER_ERROR: ob_end_clean(); halt(array( 'title' => '致命错误', 'file' => $info['file'], 'line' => $info['line'], 'message' => $info['message'], )); break; } } } /** * 中级错误处理函数 * @param integer $errno 错误级别 * @param string $errstr 错误信息 * @param string $errfile 错误文件名 * @param integer $errline 错误行号 */ static public function errorHandler($errno, $errstr, $errfile, $errline){ switch($errno){ case E_ERROR: case E_PARSE: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_USER_ERROR: ob_end_clean(); halt(array( 'title' => '中级错误', 'file' => $info['file'], 'line' => $info['line'], 'message' => $info['message'], )); break; default: Custom::log(array('line'=>$errline, 'file'=>$errfile, 'mess'=>$errstr)); break; } } static public function appException(){ //代写 } /** * call调用 * @param string $name call名 * @param string $type 类型 */ static public function call($name, $type='class'){ switch($type){ case 'function': return $name(); break; case 'class': return new $name; break; } } /** * 日志记录 * @param array $info 数据 * @param string $type 日志类型 */ static public function log($info=null, $type='E'){ static $_debug = array(); if(is_null($info)) return $_debug; if(constant('APP_DEBUG')){ $array = array( 'S' => 'System', 'T' => 'Tpl', 'Q' => 'Query', 'R' => 'Require', 'C' => 'Cache', 'E' => 'Error' ); $type = $array[strtoupper($type)]; if($type == 'System'){ if(!isset($_debug[$type])) $_debug[$type]=array(); $_debug[$type] = array_merge($_debug[$type], $info); }elseif($type == 'Cache'){ isset($_debug['Cache']['write']) || $_debug['Cache']['write']=0; isset($_debug['Cache']['success']) || $_debug['Cache']['success']=0; isset($_debug['Cache']['failure']) || $_debug['Cache']['failure']=0; if($info==0) $_debug['Cache']['write']++; elseif($info==1) $_debug['Cache']['success']++; elseif($info==2) $_debug['Cache']['failure']++; }else{ $_debug[$type][] = $info; } } } /** * 获取标签属性值 * @param string $code 参数代码 * @return array 参数组 */ static public function getTagAttrs($code){ $xml = '<tpl><tag '.$code.' /></tpl>'; $xml = simplexml_load_string($xml); if(!$xml) error('Xml tag error.'); $xml = (array)($xml->tag->attributes()); $array = array_change_key_case($xml['@attributes']); return $array; } /** * 设置默认值 * @param array $project 被设置对象 * @param array $value 对应值 */ static public function setDefaultValue(&$project, $value){ arrayCallBack($project, function($v, $k, $a){ return empty($v) ? $a : $v; }, $value); } /** * 模板解析 * @param string $code HTML代码 * @return string 解析后的PHP代码 */ static public function parsing($code){ //获取配置 $dlmter['left'] = preg_quote(C('LEFT_DLMTER')); $dlmter['right'] = preg_quote(C('RIGHT_DLMTER')); //if $code = preg_replace_callback('/'.$dlmter['left'].' *if *([^{]+?) *'.$dlmter['right'].'/', function($m){ $m[1] = preg_replace_callback('/(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_$\x7f-\xff\[\]\\\'\"\.]*)/', function($s){ return Custom::parseVar($s[1]); }, $m[1]); return '<?php if' . $m[1] . ': ?>'; }, $code); $code = preg_replace('/'.$dlmter['left'].' *else *'.$dlmter['right'].'/', '<?php else: ?>', $code); $code = preg_replace_callback('/'.$dlmter['left'].' *elseif *([^{]+?) *'.$dlmter['right'].'/', function($m){ $m[1] = preg_replace_callback('/(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_$\x7f-\xff\[\]\\\'\"\.]*)/', function($s){ return Custom::parseVar($s[1]); }, $m[1]); return '<?php elseif' . $m[1] . ': ?>'; }, $code); $code = preg_replace ('/'.$dlmter['left'].' *\/if *'.$dlmter['right'].'/', '<?php endif; ?>', $code); //foreach $code = preg_replace_callback('/'.$dlmter['left'].' *foreach *([^{]+?) *'.$dlmter['right'].'/', function($m){ $m[1] = preg_replace_callback('/(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_$\x7f-\xff\[\]\\\'\"\.]*)/', function($s){ return Custom::parseVar($s[1]); }, $m[1]); return '<?php foreach' . $m[1] . ': ?>'; }, $code); $code = preg_replace('/'.$dlmter['left'].' *\/foreach *'.$dlmter['right'].'/', '<?php endforeach; ?>', $code); //for $code = preg_replace_callback('/'.$dlmter['left'].' *for *([^{]+?) *'.$dlmter['right'].'/', function($m){ $m[1] = preg_replace_callback('/(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_$\x7f-\xff\[\]\\\'\"\.]*)/', function($s){ return Custom::parseVar($s[1]); }, $m[1]); return '<?php for' . $m[1] . ': ?>'; }, $code); $code = preg_replace('/'.$dlmter['left'].' *\/for *'.$dlmter['right'].'/', '<?php endfor; ?>', $code); //变量 $code = preg_replace_callback('/'.$dlmter['left'].' *([\+\-]*)(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_$\x7f-\xff\[\]\\\'\"\.\+\-\/\*%]*) *'.$dlmter['right'].'/', function($m){ return '<?php echo ' . $m[1] . Custom::parseVar($m[2]) . '; ?>'; }, $code); //常量 $code = preg_replace('/'.$dlmter['left'].' *([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*) *'.$dlmter['right'].'/', '<?php echo \\1; ?>', $code); //方法 $code = preg_replace_callback('/'.$dlmter['left'].'@ *(.[\s\S]*?) *'.$dlmter['right'].'/s', function($m){ $m[1] = preg_replace_callback('/(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_$\x7f-\xff\[\]\\\'\"\.]*)/', function($s){ return Custom::parseVar($s[1]); }, $m[1]); return '<?php echo (' . $m[1] . '); ?>'; }, $code); //特殊符号 $code = str_replace(array('?><?php', "?>\r\n<?php", '__TMPL__'), array('', '', getRootPath().($tmpl=C('LAYER_T') ? $tmpl : (APP_PATH_VIEW.ucfirst(MD_CTR)))), $code); //压缩处理 if(C('COMPRESS.HTML')){ $code = compress_html($code); } return $code; } /** * 删除数组中指定值对应的项 * @param [type] $value 任何值 * @param array &$array 欲处理的数组 * @param boolean $strict 是否检查类型相等 * @param integer $count 处理级别 * @return array */ static public function delArrayByValue($value, &$array, $strict=false, $count=9999999){ foreach($array as $k => $v){ if(is_array($v)){ if($count--){ self::delArrayByValue($value, $v, $strict, $count); $array[$k] = $v; if(!count($v)) unset($array[$k]); } }else{ if($strict){ if($v === $value) unset($array[$k]); }else{ if($v == $value) unset($array[$k]); } } } } /** * 变量解析 * @param string $code 代码 * @return [type] 返回变量数据 */ static public function parseVar($code, $object=false){ if(substr($code, 0, 1) == '$') $code = substr($code, 1); $arr=explode('[', $code); $key=0; while(++$key < count($arr)){ while(($num=strpos($arr[$key], ']')) !== false){ $str = substr($arr[$key], 0, $num); array_splice($arr, $key++, 0, $str); $arr[$key] = substr($arr[$key], $num+1); $arr[$key] = (substr($arr[$key], 0, 1)=='.' ? substr($arr[$key], 1) : $arr[$key]); } } self::delArrayByValue(false, $arr, true); $arr = explode('.', implode('.', $arr)); if($object) $str = '$this->' . (strpos($arr[0], "'")===false ? $arr[0] : '{\'' . self::parseSingle($arr[0]) . '\'}'); else $str = '$' . (strpos($arr[0], "'")===false ? $arr[0] : '{\'' . self::parseSingle($arr[0]) . '\'}'); foreach($arr as $key=>$value){ if($key != 0){ if(in_array(substr($value, 0, 1), array("'", '"')) && in_array(substr($value, -1), array("'", '"'))) $value = substr($value, 1, -1); $str .= '[' . (is_numeric($value) ? $value : "'" . self::parseSingle($value) . "'") . ']'; } } return $str; } /** * 单引号过滤 * @param string $str 数据 * @return string/array 处理后数据 */ static public function parseSingle($str){ return addcslashes($str, "'"); } /** * 提交数据HTML代码转义 * @param string/array $data 数据 * @return string/array 处理后数据 */ static public function runMagicQuotes($data, $filter){ if(is_array($data)){ foreach($data as $key => $value){ $data[$key] = self::runMagicQuotes($value, $filter); } }else{ $data = call_user_func($filter, $data); } return $data; } /** * 解析原生Cookie信息 * @param string $cookie Cookie文本, 为空使用当前网页Cookie * @return array Cookie组 */ static public function parseCookie($cookie=null){ if($cookie === null) $cookie = $_SERVER['HTTP_COOKIE']; $array = array(); $cookie = explode(';', $cookie); foreach($cookie as $key=>$value){ $value = trim($value); if($value){ $a = explode('=', $value); $array[$a[0]] = isset($a[1]) ? $a[1] : ''; } } return $array; } }